﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Security.Cryptography;
using System.Text;

namespace BEELab.Data
{
    public static class CryptographyHelper
    {
        //Represent all allowed characters
        static readonly char[] AvailableCharacters = {
            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 
            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 
            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 
            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
          };

        static readonly char[] AvailableDigits = {
            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
          };

        /// <summary>
        /// Generates random long int, in requested length
        /// </summary>
        /// <param name="length">Desired int length</param>
        /// <returns>String that represents the random int</returns>
        public static string GenerateRandomLongInt(int length)
        {
            char[] result = new char[length];
            byte[] randomData = new byte[length];

            using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(randomData);
            }

            for (int idx = 0; idx < result.Length; idx++)
            {
                int pos = randomData[idx] % AvailableDigits.Length;
                result[idx] = AvailableDigits[pos];
            }

            return new string(result);
        }

        /// <summary>
        /// Generates random string in requested length.
        /// (For example: Used in order to reset passwords securely).
        /// </summary>
        /// <param name="length">String length</param>
        /// <returns>Random string</returns>
        public static string GenerateRandomString(int length)
        {
            char[] result = new char[length];
            byte[] randomData = new byte[length];

            using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
            {
                rng.GetBytes(randomData);
            }

            for (int idx = 0; idx < result.Length; idx++)
            {
                int pos = randomData[idx] % AvailableCharacters.Length;
                result[idx] = AvailableCharacters[pos];
            }

            return new string(result);
        }

        /// <summary>
        /// Gets plain and creates its hash string according to hashing algorithm.
        /// </summary>
        /// <param name="text">Plain text</param>
        /// <returns>Cipher/Hashed text</returns>
        public static string Hash(string text)
        {
            SHA256Managed hashstring = new SHA256Managed();
            byte[] bytes = Encoding.UTF8.GetBytes(text);
            byte[] hash = hashstring.ComputeHash(bytes);
            string hashString = string.Empty;
            foreach (byte x in hash)
            {
                hashString += String.Format("{0:x2}", x);
            }
            return hashString;
        }
    }
}